<template>
	<div class="music">
		<div class="innerContent">
			<!-- 图片 -->
			<div
				class="picUrl"
				:style="{
					'animation-play-state': isPlay ? 'running' : 'paused',
				}"
			>
				<img :src="picUrl" />
			</div>
			<!-- 歌曲信息 -->
			<div
				class="musicCommon musicInfo"
				v-show="!isMouseEnter"
				@mouseenter="isMouseEnter = !isMouseEnter"
			>
				<div class="singer" v-show="!name">暂未播放音乐</div>
				<div class="musicName" v-show="name">
					<span>{{ name.split("-")[0] }}</span>
				</div>
				<div class="singer" v-show="name">
					<span>{{ name.split("-")[1] }}</span>
				</div>
			</div>
			<!-- 歌曲操作 -->
			<div
				class="musicCommon musicSetting"
				v-show="isMouseEnter"
				@mouseleave="isMouseEnter = !isMouseEnter"
			>
				<!-- 关闭 -->
				<!-- <i
					class="el-icon-close"
					@click="$electron.ipcRenderer.send('music-close')"
				></i> -->
				<!-- 音量 -->
				<el-popover placement="right" trigger="hover">
					<el-slider
						v-model="volume"
						@input="changeVolume"
					></el-slider>
					<i
						slot="reference"
						class="iconfont volume"
						:class="
							volume > 50
								? 'icon-yinliang'
								: volume > 0
								? 'icon-shengyin'
								: 'icon-jingyin'
						"
						@click="handleVolume"
					></i>
				</el-popover>
				<!-- 播放 暂停 -->
				<i
					class="iconfont"
					:class="`icon-${isPlay ? 'pause' : 'play'}`"
					:title="isPlay ? '暂停' : '开始'"
					@click="changePlayState"
					id="play"
				></i>
				<!-- 下一曲 -->
				<i class="iconfont icon-play-next4" @click="nextMusic"></i>
			</div>
			<!-- 歌词 -->
			<div class="lyric">
				<span ref="lyric">{{ currentLyric }}</span>
			</div>
			<!-- 下一首 -->
			<div class="nextMusic">
				<div>
					<p>下一首：</p>
					<div>
						<span>{{
							musicList.length
								? musicList[0].uname +
								  " 点了首 " +
								  musicList[0].name
								: "暂无点歌信息，随机播放！"
						}}</span>
					</div>
				</div>
				<div class="switch">
					切歌：{{ switchMusicList.size }} / {{ switchMusicNum }}
				</div>
			</div>
			<!-- 歌曲进度条 -->
			<div class="progress">
				<div class="time currentTime">
					{{ handleTime(currentTime) }}
				</div>
				<el-slider
					v-model="slider"
					:show-tooltip="false"
					@change="sliderChange"
				></el-slider>
				<div class="time duration">
					{{ handleTime(duration) }}
				</div>
			</div>
		</div>
	</div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import { nanoid } from "nanoid";
import Lyric from "lrc-file-parser";
export default {
	data() {
		return {
			// 播放的音乐
			music: new Audio(),
			// 音乐图片路径
			picUrl: "https://www.ayangweb.cn/img/avatar.8d018298.jpg",
			// 切歌需要总人数
			switchMusicNum: localStorage.getItem("switchMusicNum") || 3,
			// 切歌人数
			switchMusicList: new Set(),
			// 歌曲名称
			name: "",
			// 歌曲总时长
			duration: 0,
			// 歌曲当前时长
			currentTime: 0,
			// 音乐是否在播放
			isPlay: false,
			// 音乐进度条
			slider: 0,
			// 歌单列表
			songList: [],
			// 歌单列表index
			songListIndex: 0,
			// 音量
			volume: parseInt(localStorage.getItem("musicVolume")) || 40,
			// 歌词
			lyric: null,
			// 当前显示的歌词
			currentLyric: "暂未播放音乐",
			// 当前要播放音乐的基本信息
			currentMusicInfo: null,
			// 鼠标是否进入 (歌曲基本信息和设置的互换)
			isMouseEnter: false,
			// 没有歌词吗?
			nolyric: true,
		};
	},
	mounted() {
		// 监听 点歌
		this.$electron.remote.ipcMain.on("addMusic", (e, { uname, val }) => {
			this.appendMusic({
				uname,
				name: val,
			});
		});
		// 监听 切歌
		this.$electron.remote.ipcMain.on("switchMusic", (e, uname) => {
			this.switchMusicList.add(uname);
			this.switchMusicList.size == this.switchMusicNum &&
				this.nextMusic();
		});
		// 监听切歌人数的变化
		this.$electron.remote.ipcMain.on("switchMusicNum", (e, val) => {
			this.switchMusicList.clear();
			this.switchMusicNum = val;
		});
		// 监听音乐是否播放完
		this.music.addEventListener("ended", () => {
			this.isPlay = false;
			this.nextMusic();
		});
		// 监听音乐改变当前播放的时间
		this.changeCurrentTime();
		// 没有点歌, 播放默认歌单
		this.playSongList();
	},
	methods: {
		...mapMutations(["appendMusic", "nextMusic"]),
		...mapActions(["sendMsg"]),
		// 将数字时间处理为mm:ss
		handleTime(time) {
			const minutes = "0" + Math.floor(time / 60);
			const seconds = "0" + (time - minutes * 60);
			return minutes.substr(-2) + ":" + seconds.substr(-2);
		},
		// 搜索歌曲
		searchMusic({ uname, name }) {
			this.axios
				.get(
					`https://music-node.vercel.app/cloudsearch?keywords=${name}`
				)
				.then((res) => {
					const result = res.data.result.songs;
					if (!result || !result.length) {
						uname &&
							this.$electron.ipcRenderer.send("appendAutoReply", {
								uname,
								message: "没有此歌，换首歌试试",
							});
						this.nextMusic();
					} else {
						const singData = {
							id: nanoid(),
							url: `http://music.163.com/song/media/outer/url?id=${result[0].id}.mp3`,
							name: result[0].name + " - " + result[0].ar[0].name,
							duration: result[0].dt.toString().slice(0, -3),
							picUrl: result[0].al.picUrl,
						};
						this.searchLyric(result[0].id)
							.then((res) => {
								this.nolyric = false;
								this.splitLyric(res);
								this.playMusic(singData);
							})
							.catch((err) => {
								this.nolyric = true;
								this.playMusic(singData);
							});
					}
				});
		},
		// 搜索歌词
		searchLyric(id) {
			const lyricRes = new Promise((resolve, reject) => {
				this.axios
					.get(`https://music-node.vercel.app/lyric?id=${id}`)
					.then((res) => {
						// res.data.nolyric true 无歌词
						res.data.nolyric
							? reject()
							: resolve(res.data.lrc.lyric);
					});
			});
			return lyricRes;
		},
		// 处理歌词
		splitLyric(lyric) {
			const that = this;
			that.lyric = new Lyric({
				onPlay(line, text) {
					that.currentLyric = text;
				},
				offset: 0,
			});
			this.lyric.setLyric(lyric);
		},
		// 播放音乐
		playMusic({ url, name, duration, picUrl }) {
			this.switchMusicList.clear();
			this.name = name;
			this.duration = duration;
			this.music.src = url;
			this.picUrl = picUrl;
			this.music.volume = this.volume / 100;
			this.music
				.play()
				.then((res) => {
					this.isPlay = true;
					this.nolyric
						? ((this.lyric = null),
						  (this.currentLyric = "纯音乐，暂无歌词！"))
						: this.lyric.play(this.music.currentTime * 1000);
				})
				.catch((res) => {
					this.$message.error({
						message: "阿偶，播放失败了，貌似没有版权吧~",
						duration: 1500,
					});
					this.nextMusic();
				});
		},
		// 音乐的播放与暂停
		changePlayState() {
			if (this.isPlay) {
				this.music.pause();
				!this.nolyric && this.lyric.pause();
			} else {
				this.music.play();
				!this.nolyric && this.lyric.play(this.music.currentTime * 1000);
			}
			this.isPlay = !this.isPlay;
		},
		// 监听音乐改变当前播放的时间
		changeCurrentTime() {
			this.music.addEventListener("timeupdate", () => {
				this.currentTime = Math.floor(this.music.currentTime);
				this.slider = this.currentTime / (this.duration / 100);
			});
		},
		// 进度条滑块滑动
		sliderChange(val) {
			this.music.currentTime = Math.floor(val * (this.duration / 100));
			this.music.play();
			this.isPlay = true;
			!this.nolyric && this.lyric.play(this.music.currentTime * 1000);
		},
		// 歌单空了就播放歌单音乐
		playSongList() {
			const songListIdList = localStorage
				.getItem("songListId")
				.split(",");
			const songListId = songListIdList[this.songListIndex] || 3778678;
			if (this.songList.length) {
				const name = this.songList[
					Math.floor(Math.random() * this.songList.length)
				].id;
				const spliceId = this.songList.findIndex(
					(item) => item.id == name
				);
				this.songList.splice(spliceId, 1);
				this.appendMusic({
					name,
				});
			} else {
				this.axios
					.get(
						`https://music-node.vercel.app/playlist/detail?id=${songListId}`
					)
					.then((res) => {
						const name =
							res.data.privileges[
								Math.floor(
									Math.random() * res.data.privileges.length
								)
							].id;
						this.appendMusic({ name });
						const spliceId = res.data.privileges.findIndex(
							(item) => item.id == name
						);
						res.data.privileges.splice(spliceId, 1);
						this.songList = res.data.privileges;
						this.songListIndex++;
					})
					.catch((err) => {
						this.$message.error({
							message: "当前歌单无法播放，开始播放下一个歌单！",
							duration: 3000,
						});
						const deleteId = songListIdList.findIndex(
							(item) => item == songListId
						);
						songListIdList.splice(deleteId, 1);
						this.$electron.ipcRenderer.send(
							"deleteSomeSongListId",
							songListIdList.join(",")
						);
						this.musicList.length
							? this.nextMusic()
							: this.playSongList();
					});
			}
		},
		// 改变音乐大小
		changeVolume(val) {
			this.music.volume = val / 100;
			localStorage.setItem("musicVolume", val);
		},
		// 点击音量图标
		handleVolume() {
			this.volume > 0 ? (this.volume = 0) : (this.volume = 40);
		},
	},
	computed: {
		...mapState(["currentMusic", "musicList"]),
	},
	watch: {
		currentMusic(newVal) {
			!this.nolyric && this.lyric.pause();
			newVal ? this.searchMusic(newVal) : this.playSongList();
		},
	},
};
</script>

<style lang="scss">
.music {
	height: 100vh;
	padding: 20px 10px;
	user-select: none;
	.innerContent {
		position: relative;
		height: 100%;
		padding: 5px 10px 0;
		border-radius: 10px;
		background-color: #fff;
		box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
		-webkit-app-region: drag;
		// 图片
		.picUrl {
			overflow: hidden;
			position: absolute;
			top: -20px;
			width: 75px;
			height: 75px;
			border-radius: 50%;
			border: 2px solid rgba(0, 0, 0, 0.2);
			animation: picUrl 8s linear infinite;
			img {
				width: 100%;
			}
		}
		@keyframes picUrl {
			0% {
				transform: rotate(0);
			}
			100% {
				transform: rotate(360deg);
			}
		}
		// 歌曲信息
		.musicCommon {
			display: flex;
			justify-content: center;
			align-items: center;
			width: 50%;
			height: 50px;
			margin: 0 auto;
			font-size: 14px;
			-webkit-app-region: no-drag;
			&.musicInfo {
				flex-direction: column;
				div {
					width: 100%;
					overflow: hidden;
					white-space: nowrap;
					text-align: center;
					&.singer {
						padding-top: 5px;
						color: #808080;
					}
					span {
						display: inline-block;
						min-width: 100%;
						animation: musicInfo 8s ease-in-out infinite alternate;
					}
				}
				@keyframes musicInfo {
					0% {
						transform: translateX(0);
					}
					100% {
						transform: translateX(calc(180px - 100%));
					}
				}
			}
			&.musicSetting {
				position: relative;
				i {
					font-size: 24px;
					cursor: pointer;
					border: 0;
					outline: 0;
					-webkit-app-region: no-drag;
					&.el-icon-close {
						font-size: 18px;
						position: absolute;
						top: 0;
						right: -95px;
					}
					&#play {
						font-size: 30px;
						color: #00a1d6;
						margin: 0 10px;
					}
					&.volume {
						font-size: 20px;
					}
					&:hover {
						color: #00a1d6;
					}
				}
			}
		}
		// 歌词
		.lyric {
			overflow: hidden;
			white-space: nowrap;
			padding-top: 5px;
			font-size: 14px;
			text-align: center;
			// color: #409eff;
			span {
				display: inline-block;
				min-width: 100%;
				animation: lyric 5s ease-in-out infinite alternate;
			}
			@keyframes lyric {
				0% {
					transform: translateX(0);
				}
				100% {
					transform: translateX(calc(360px - 100%));
				}
			}
		}
		// 下一首
		.nextMusic {
			display: flex;
			justify-content: space-between;
			padding-top: 7px;
			font-size: 14px;
			> div {
				display: flex;

				width: 270px;
				&.switch {
					width: 90px;
					justify-content: flex-end;
				}
				> div {
					width: calc(100% - 56px);
					overflow: hidden;
					white-space: nowrap;
					span {
						display: inline-block;
						min-width: 100%;
						animation: nextMusic 8s ease-in-out infinite alternate;
					}
				}
			}
			@keyframes nextMusic {
				0% {
					transform: translateX(0);
				}
				100% {
					transform: translateX(calc(214px - 100%));
				}
			}
		}
		// 进度条
		.progress {
			display: flex;
			align-items: center;
			justify-content: space-between;
			transform: translateY(-4px);
			-webkit-app-region: no-drag;
			.time {
				width: 60px;
				font-size: 12px;
				&.duration {
					text-align: right;
				}
			}
			.el-slider {
				width: 100%;
				transform: translateY(0.5px);
				.el-slider__runway {
					.el-slider__button-wrapper {
						display: none;
					}
					&:hover {
						.el-slider__button-wrapper {
							display: block;
						}
					}
				}
			}
		}
	}
}
.el-popover {
	-webkit-app-region: no-drag;
}
.el-popper[x-placement^="right"] {
	margin-left: 0 !important;
}
</style>
